package com.redis.util;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisZSetCommands;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;

/**
 * @Author Tanyu
 * @Date 2020/6/2 9:19
 * @Description RedisTemplate()方法的一些常用方法
 * @Version 1.0
 */
public class RedisTemplateUtils {

  //先引入RedisTemplate
  @Autowired
  private RedisTemplate redisTemplate;

  public void redisInfo() {
    //add(K key, V value, double score) 添加元素到变量中同时指定元素的分值
    redisTemplate.opsForZSet().add("value", "A", 1);
    redisTemplate.opsForZSet().add("value", "B", 3);
    redisTemplate.opsForZSet().add("value", "C", 2);

    //add(K key, Set<ZSetOperations.TypedTuple> tuples) 添加tuples到排序集key，或者score如果已存在则更新它。
    ZSetOperations.TypedTuple<Object> typedTuple1 = new DefaultTypedTuple<Object>("A", 6.0);
    ZSetOperations.TypedTuple<Object> typedTuple2 = new DefaultTypedTuple<Object>("B", 7.0);
    ZSetOperations.TypedTuple<Object> typedTuple3 = new DefaultTypedTuple<Object>("C", 5.0);
    Set<TypedTuple<Object>> typedTupleSet = new HashSet<TypedTuple<Object>>();
    typedTupleSet.add(typedTuple1);
    typedTupleSet.add(typedTuple2);
    typedTupleSet.add(typedTuple3);
    redisTemplate.opsForZSet().add("typedTupleSet", typedTupleSet);
    Set valueSet = redisTemplate.opsForZSet().range("typedTupleSet", 0, -1);
    System.out.println(valueSet);

    //rank(K key, Object o) 获取变量中元素的索引值
    long index = redisTemplate.opsForZSet().rank("value", "B");
    System.out.println(index);

    //count(K key, double min, double max) 获取区间值的个数。
    long count = redisTemplate.opsForZSet().count("zSetValue", 1, 5);
    System.out.println(count);

    //range(K key, long start, long end) 获取变量指定区间的元素
    Set valueSet0 = redisTemplate.opsForZSet().range("value", 0, -1);
    System.out.println(valueSet0);

    //rangeByLex(K key, RedisZSetCommands.Range range) 用于获取满足非score的排序取值。
    //这个排序只有在有相同分数的情况下才能使用，如果有不同的分数则返回值不确定。
    RedisZSetCommands.Range range = new RedisZSetCommands.Range();
    //range.gt("A");
    range.lt("B");
    Set valueSet1 = redisTemplate.opsForZSet().rangeByLex("value", range);
    System.out.println(valueSet1);

    //根据设置的score获取区间值。
    Set valueSet2 = redisTemplate.opsForZSet().rangeByScore("zSetValue", 1, 2);
    System.out.println(valueSet2);

    //8、incrementScore(K key, V value, double delta) 修改元素的分值。
    double incrementScore = redisTemplate.opsForZSet().incrementScore("zSetValue", "A", 5);

    //获取元素的分值
    Double score = redisTemplate.opsForZSet().score("zSetValue", "A");
    System.out.println("修改后A的分值:" + score);

    //rangeByScoreWithScores(K key, double min, double max)
    //正序获取RedisZSetCommands.Tuples的区间值通过分值。
    Set<ZSetOperations.TypedTuple<Object>> typedTupleSet1 = redisTemplate.opsForZSet()
        .rangeByScoreWithScores("typedTupleSet", 5, 8);
    Iterator<TypedTuple<Object>> iterator = typedTupleSet1.iterator();
    while (iterator.hasNext()) {
      ZSetOperations.TypedTuple<Object> typedTuple = iterator.next();
      Object value = typedTuple.getValue();
      double score1 = typedTuple.getScore();
      System.out.println(value + "----" + score1);
    }

    //reverseRangeByScoreWithScores(K key, double min, double max)
    //倒序排序获取RedisZSetCommands.Tuples的分值区间值。
    Set<ZSetOperations.TypedTuple<Object>> typedTupleSet2 = redisTemplate.opsForZSet()
        .reverseRangeByScoreWithScores("zSetValue", 1, 5);
    iterator = typedTupleSet2.iterator();
    while (iterator.hasNext()) {
      ZSetOperations.TypedTuple<Object> typedTuple = iterator.next();
      Object value = typedTuple.getValue();
      double score2 = typedTuple.getScore();
      System.out.println(value + "----" + score2);
    }

  }

}
